/*!
 * \file    uvga.cpp
 * \class   uVGA
 *
 * \author  Adrien Bougouin <adrien.bougouin@gmail.com>
 */

#include "uvga.h"

void uVGA::begin(const unsigned int baud) const {
  // open channel
  Serial.begin(baud);

  // waiting for the VGA to be ready and start the communication
  delay(AWAKE_DELAY);
  send_cmd(WAKE_CMD, NULL, true); // TODO verifier si le true est necessaire
}

void uVGA::send_cmd(const char cmd,
                    const char **args,
                    bool need_delay_after_cmd) const {
  Serial.print(cmd, BYTE);

  while(*args) {
    Serial.print(**args, BYTE);

    ++args;
  }

  if(need_delay_after_cmd) {
    delay(DELAY_AFTER_CMD);
  }
}

char uVGA::uvga_response() const {
  return Serial.read();
}

/*******************************************************************************
 * Commands
 */

void uVGA::erase_screen() const {
  send_cmd(ERASE_CMD, NULL, true);
}

void uVGA::background_color(const char color) const {
  const char *args[2] = {&color, NULL};

  send_cmd(BACKGROUND_CMD, args);
}

void uVGA::put_pixel(const short int x,
                     const short int y,
                     const char color) const {
  const char x_lsb = x;
  const char x_msb = x >> 8;
  const char y_lsb = y;
  const char y_msb = y >> 8;
  const char *args[6] = {&x_msb, &x_lsb, &y_msb, &y_lsb, &color, NULL};

  send_cmd(PUT_PIXEL_CMD, args);
}

////////////////////////////////////////////////////////////////////////////////
// TODO TESTER
////////////////////////////////////////////////////////////////////////////////

char uVGA::read_pixel(const short int x,
                      const short int y,
                      const char color) const {
  const char x_lsb = x;
  const char x_msb = x >> 8;
  const char y_lsb = y;
  const char y_msb = y >> 8;
  const char *args[6] = {&x_msb, &x_lsb, &y_msb, &y_lsb, &color, NULL};

  send_cmd(READ_PIXEL_CMD, args);

  return uvga_response();
}

void uVGA::draw_circle(const short int x,
                       const short int y,
                       const char radius,
                       const char color) const {
  const char x_lsb = x;
  const char x_msb = x >> 8;
  const char y_lsb = y;
  const char y_msb = y >> 8;
  const char *args[7] = {&x_msb, &x_lsb, &y_msb, &y_lsb, &radius, &color, NULL};

  send_cmd(DRAW_CIRCLE_CMD, args);
}

void uVGA::draw_line(const short int x1,
                     const short int y1,
                     const short int x2,
                     const short int y2,
                     const char color) const {
  const char x1_lsb = x1;
  const char x1_msb = x1 >> 8;
  const char y1_lsb = y1;
  const char y1_msb = y1 >> 8;
  const char x2_lsb = x2;
  const char x2_msb = x2 >> 8;
  const char y2_lsb = y2;
  const char y2_msb = y2 >> 8;
  const char *args[10] = {&x1_msb, &x1_lsb, &y1_msb, &y1_lsb,
                         &x2_msb, &x2_lsb, &y2_msb, &y2_lsb,
                         &color, NULL};

  send_cmd(DRAW_LINE_CMD, args);
}

void uVGA::font_size(const char font_size) const {
  const char *args[2] = {&font_size, NULL};

  send_cmd(FONT_SIZE_CMD, args);
}

void uVGA::opaque_or_transparent_text(const char mode) const {
  const char *args[2] = {&mode, NULL};

  send_cmd(OPAQUE_TRANSPARENT_TEXT_CMD_CMD, args);
}

void uVGA::place_formatted_text_character(const char character,
                                          const char column,
                                          const char row,
                                          const char color) const {
  const char *args[5] = {&character, &column, &row, &color, NULL};

  send_cmd(PLACE_FORMATTED_TEXT_CHARACTER_CMD_CMD, args);
}

void uVGA::place_unformatted_text_character(const char character,
                                            const short int x,
                                            const short int y,
                                            const char color,
                                            const char x_size,
                                            const char y_size) const {
  const char x_lsb = x;
  const char x_msb = x >> 8;
  const char y_lsb = y;
  const char y_msb = y >> 8;
  const char *args[9] = {&character,
                         &x_msb, &x_lsb,
                         &y_msb, &y_lsb,
                         &color,
                         &x_size, &y_size, NULL};

  send_cmd(PLACE_UNFORMATTED_TEXT_CHARACTER_CMD_CMD, args);
}

